import React from 'react';
import PropTypes from 'prop-types';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { Table, Popconfirm, Spin } from 'antd';
import PrimaryGhostC from '../button/primaryGhost';
import accounting from 'accounting';
import { connect } from 'dva';
import SiderMenuWidth from '../../css/frame';
const siderWidth = SiderMenuWidth.width - SiderMenuWidth.collapsedWidth;
class NewTableC extends React.Component {
  // props默认值
  static defaultProps = {
    columns: undefined,
    dataSource: undefined,
    defaultCurrent: undefined, // 默认第一页
    current: undefined,
    total: 0, // 默认共0条数据
    pageSize: 20, // 默认一页20条
    pageSizeOptions: ['10', '20', '50', '100'], // 默认可选的一页条数
    onShowSizeChange: (current, size) => {}, // pageSize变化时的回调
    onPageChange: (page, pageSize) => {}, // 页码改变的回调，参数是改变后的页码及每页条数
    scroll: undefined, // 横向或纵向滚动条
    hidePage: false, // 默认不隐藏页码
    width: '100%', // 默认占父容器100%
    onChange: () => {}, // 表格所有的操作变化时 回调
    onExpand: () => {}, // 点击展开图标时触发
    expandedRowKeys: undefined, // 展开的节点
    rowKey: '', // 设置唯一的key
    rowClassName: '', //设置行样式
    loading: false,
    simple: false,
  };
  state = {
    collapsed: undefined, //侧边菜单栏是否合并
    sizePage: undefined,
  };
  UNSAFE_componentWillReceiveProps(nextProps) {
    if (nextProps.globalM.collapsed !== undefined && nextProps.globalM.collapsed !== this.state.collapsed) {
      this.setState(
        {
          collapsed: nextProps.globalM.collapsed,
        },
        () => {
          this.getTableDom(this.state.collapsed);
          /**窗口改变大小时触发*/
          window.onresize = () => {
            this.getTableDom(this.state.collapsed, 'noCalc');
          };
        },
      );
    }
  }
  //获取表格dom
  getTableDom = (collapsed, type) => {
    let tempWidth;
    if (this.refs.table) {
      clearInterval(this.timerGetDom);
      this.timerGetDom = null;
      if (type || !this.state.width) {
        //窗口变化、页面初始化时不额外进行计算宽度
        tempWidth = this.refs.table.offsetWidth;
      } else {
        //收缩侧边菜单 宽度进行增减
        tempWidth = collapsed ? this.refs.table.offsetWidth + siderWidth : this.refs.table.offsetWidth - siderWidth;
      }
    } else {
      clearInterval(this.timerGetDom);
      this.timerGetDom = setTimeout(() => {
        this.getTableDom(collapsed);
      }, 500);
    }

    this.setState({
      width: tempWidth,
    });

    if (tempWidth < 800) {
      this.setState({ sizePage: 'small' });
    } else {
      this.setState({ sizePage: undefined });
    }
  };
  render() {
    let {
      columns,
      size,
      simple,
      dataSource,
      total,
      defaultCurrent,
      pageSizeOptions,
      onShowSizeChange,
      onPageChange,
      scroll,
      hidePage,
      width,
      onChange,
      rowKey,
      onExpand,
      expandedRowKeys,
      current,
      pageSize,
      rowClassName,
      onRow,
      rowSelection,
      loading,
      expandedRowRender,
    } = this.props;
    var otherWidth = 0; //其他固定列之和
    var autoWidth = 0;
    const hidden = {
      overflow: 'hidden',
      textOverflow: 'ellipsis',
      whiteSpace: 'nowrap',
    };
    columns &&
      columns.forEach((element, index) => {
        if (!element.ellipsis) otherWidth += element.width * 1 || 0; //
        // 为每一列添加dataIndex
        element.dataIndex = element.key;
        // 如果有子节点，也为每个子节点添加dataIndex
        element.children && element.children.forEach((item) => (item.dataIndex = item.key));
        // 设置最后一列居右
        if (index == columns.length - 1) {
          element.align = element.align ? element.align : 'right';
        }
        // 设置除操作列外列宽度
        if (element.type !== 'operate') {
          element.width = element.title.length * 27;
        }
        // 数字居右
        if (element.type === 'number') {
          element.align = element.align ? element.align : 'right';
          if (element.render === undefined) {
            element.render = (text, record, index) => {
              if (text === null || text === undefined) {
                return '--';
              } else {
                if (isNaN(text)) {
                  return text;
                } else {
                  return Number(text).toFixed(element.toFixed ? element.toFixed : 2);
                }
              }
            };
          }
        }
        // 金钱（千分位格式，默认保留2位小数，支持通过toFixed修改保留位数）
        if (element.type === 'money') {
          element.align = element.align ? element.align : 'right';
          if (element.render === undefined) {
            element.render = (text, record, index) => {
              if (text === null || text === undefined) {
                return '--';
              } else {
                return accounting.formatNumber(Number(text), element.toFixed ? element.toFixed : 2);
              }
            };
          }
        }
        // 比率（%格式，默认保留2位小数，支持通过toFixed修改保留位数）
        if (element.type === 'rate') {
          element.align = element.align ? element.align : 'right';
          if (element.render === undefined) {
            element.render = (text, record, index) => {
              if (text === null || text === undefined) {
                return '--';
              } else {
                // NaN: Not a Number
                // isNaN()的缺点就在于 null、空格以及空串会被按照0来处理
                if (isNaN(text)) {
                  return text;
                } else {
                  return (Number(text) * 100).toFixed(element.toFixed ? element.toFixed : 2) + '%';
                }
              }
            };
          }
        }
        // 处理所有没有值的情况
        if (element.render === undefined) {
          element.render = (text, record, index) => (text === null || text === undefined ? '--' : text);
        }
        // 操作列
        if (element.type === 'operate') {
          const operates = element.operates;
          element.render = (text, record, index) => {
            return (
              <div>
                {operates.map((item, index) => {
                  const rules = item.rules;
                  let hide = true;
                  let disabled = true;
                  // 默认不同字段，条件之间是与关系，同字段，条件之间是或的关系（同字段的或关系未实现，需扩展），
                  // 当设置了relation是or时，不同字段条件之间的关系是或
                  // 处理隐藏逻辑
                  if (rules && rules.hide) {
                    if (rules.hide.relation === 'or') {
                      let tag = false;
                      rules.hide.items.forEach((eachRule) => {
                        // 处理不同字段之间的或关系
                        let value = record[eachRule.key];
                        let compare = eachRule.value;
                        let relation = eachRule.relation;
                        for (let i = 0; i < compare.length; i++) {
                          switch (relation[i]) {
                            case '=':
                              if (value === compare[i]) tag = tag || true;
                              break;
                            case '!=':
                              if (value !== compare[i]) tag = tag || true;
                              break;
                          }
                        }
                      });
                      hide = tag;
                    } else {
                      rules.hide.items.forEach((eachRule) => {
                        // 处理不同字段之间的与关系
                        let value = record[eachRule.key];
                        let compare = eachRule.value;
                        let relation = eachRule.relation;
                        let tag = false;
                        for (let i = 0; i < compare.length; i++) {
                          switch (relation[i]) {
                            case '=':
                              if (value === compare[i]) tag = true;
                              break;
                            case '!=':
                              if (value !== compare[i]) tag = true;
                              break;
                          }
                        }
                        if (tag === false) hide = false;
                      });
                    }
                  } else {
                    hide = false;
                  }
                  // 处理禁用逻辑
                  if (rules && rules.disabled) {
                    if (rules.disabled.relation === 'or') {
                      let tag = false;
                      rules.disabled.items.forEach((eachRule) => {
                        // 处理不同字段之间的与关系
                        let value = record[eachRule.key];
                        let compare = eachRule.value;
                        let relation = eachRule.relation;

                        for (let i = 0; i < compare.length; i++) {
                          switch (relation[i]) {
                            case '=':
                              if (value === compare[i]) tag = true;
                              break;
                            case '!=':
                              if (value !== compare[i]) tag = true;
                              break;
                          }
                        }
                      });
                      disabled = tag;
                    } else {
                      rules.disabled.items.forEach((eachRule) => {
                        // 处理不同字段之间的与关系
                        let value = record[eachRule.key];
                        let compare = eachRule.value;
                        let relation = eachRule.relation;
                        let tag = false;
                        for (let i = 0; i < compare.length; i++) {
                          switch (relation[i]) {
                            case '=':
                              if (value === compare[i]) tag = true;
                              break;
                            case '!=':
                              if (value !== compare[i]) tag = true;
                              break;
                          }
                        }
                        if (tag === false) disabled = false;
                      });
                    }
                  } else {
                    disabled = false;
                  }

                  if (item.title === '删除' || item.title === '回退') {
                    return (
                      !hide && (
                        <Popconfirm
                          key={index}
                          title={item.title === '删除' ? '确定删除？' : '确定回退？'}
                          icon={<QuestionCircleOutlined />}
                          onConfirm={(e) => {
                            item.onClick(record, index);
                          }}
                          disabled={disabled}
                          //   onClick={(e)=> {
                          //     e.stopPropagation(); //阻止冒泡
                          //     item.onClick(record, index)
                          //   }
                          // }
                        >
                          <a disabled={disabled}>{item.title}</a>
                        </Popconfirm>
                      )
                    );
                  } else {
                    return (
                      !hide && (
                        <a
                          key={index}
                          onClick={(e) => {
                            e.stopPropagation(); //阻止冒泡
                            item.onClick(record, index);
                          }}
                          disabled={disabled}
                        >
                          {item.title}
                        </a>
                      )
                    );
                  }
                })}
              </div>
            );
          };
        }
      });

    if (this.refs.table) {
      //设置省略列的宽度
      if (scroll && scroll.x && typeof scroll.x == 'number') {
        //如果x轴滚动，只支持x设置固定值
        autoWidth = scroll.x - otherWidth - 10; //减去数值10 是y轴滚动条的预留宽度
      } else {
        autoWidth = this.state.width ? this.state.width - otherWidth - 10 : this.refs.table.offsetWidth - otherWidth - 10;
      }
      columns &&
        columns.forEach((item, index) => {
          if (item.ellipsis) {
            //设置了省略的列 render被重置
            if (autoWidth) item.width = Math.floor(autoWidth * (item.ratio || 1)); //如果只有一列省略 默认占比100%

            item.render = (text, record, index) => {
              if (text === null || text === undefined) {
                return '--';
              } else {
                // 减去数值22 是单元格的padding及左右边框
                return (
                  <span title={text} style={width ? { width: autoWidth * (item.ratio || 1) - 22, display: 'block', ...hidden } : {}}>
                    {text}
                  </span>
                );
              }
            };
          }
        });
    }
    let initStatus = columns && dataSource; // 标记是否达到初始化状态(true:可以初始化表格，false：还未获取到数据)
    let tableInfo = {};
    if (expandedRowKeys != undefined) {
      tableInfo.expandedRowKeys = expandedRowKeys;
    }
    return (
      <div style={{ width: width, textAlign: 'center' }} ref={'table'}>
        <Spin spinning={!initStatus} tip='加载中...'>
          {initStatus && (
            <Table
              {...tableInfo}
              columns={columns}
              dataSource={dataSource}
              rowClassName={rowClassName}
              scroll={scroll}
              onChange={onChange}
              rowKey={rowKey}
              onExpand={onExpand}
              expandedRowRender={expandedRowRender}
              loading={loading}
              // expandedRowKeys={expandedRowKeys}
              onRow={onRow}
              rowSelection={rowSelection}
              pagination={
                hidePage
                  ? false
                  : {
                      total: total, // 数据总数
                      showTotal: (totalNum) => `共计 ${totalNum} 条`, // 用于显示数据总量和当前数据顺序
                      defaultCurrent, // 默认当前页数
                      current: current, // 实时更新当前页码
                      pageSize, // 每页条数
                      pageSizeOptions: pageSizeOptions, // 指定每页可以显示多少条
                      showSizeChanger: true, // 是否可以改变 pageSize
                      onShowSizeChange: onShowSizeChange, // pageSize 变化的回调
                      hideOnSinglePage: false, // 只有一页时，不隐藏分页
                      onChange: onPageChange,
                      size: size || this.state.sizePage,
                      simple: simple,
                      showQuickJumper:
                        size == 'small' || this.state.sizePage == 'small'
                          ? ''
                          : {
                              goButton: <PrimaryGhostC title='确定' style={{ marginLeft: '10px' }} />,
                            },
                    }
              }
            />
          )}
        </Spin>
      </div>
    );
  }
}

// props类型
// columns或dataSource为undefined时，为loading状态，为空数组时，显示“暂无数据”
NewTableC.propsTypes = {
  columns: PropTypes.array, // 列信息(title和key是必填)（支持设置三类type:1)money 2)number 3)rate 4)operate，其他有关样式上的需求，自行添加render）
  dataSource: PropTypes.array, // 数据源
  defaultCurrent: PropTypes.number, // 当前页码
  total: 0, // 数据总量
  pageSize: 20, // 一页数量量
  pageSizeOptions: PropTypes.array, // 一页数据量的可选值
  onShowSizeChange: (current, size) => {}, // pageSize变化时的回调
  onPageChange: (page, pageSize) => {}, // 页码改变的回调，参数是改变后的页码及每页条数
  scroll: undefined, // 横向或纵向滚动条
  hidePage: false, // 默认不隐藏页码
  width: PropTypes.string, // 表格宽度
  onChange: () => {}, // 表格所有的操作变化时 回调
  onExpand: (expanded, record) => {}, // 点击展开图标时触发
  onRow: (record) => {}, // 行属性
  expandedRowKeys: PropTypes.array, // 展开的节点
  rowKey: PropTypes.string, // 设置唯一的key
  current: PropTypes.number, // 实时更新当前页码
  size: PropTypes.string, // 分页器尺寸
  rowClassName: PropTypes.oneOfType([
    //设置行样式
    PropTypes.string,
    PropTypes.func,
  ]),
  loading: PropTypes.bool, // 加载中状态
  rowSelection: PropTypes.object, //表格行是否可选择
  expandedRowRender: () => {}, //展开的嵌套内容渲染
  collapsed: PropTypes.bool, //单元格省略时必须入参 true/false
};

export default connect(({ globalM }) => ({ globalM }))(NewTableC);
